using System;
using System.Windows.Forms;
using DevExpress.Utils;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Controls;
using E4RPDevExpress;
using E4RPTools;
using ZecaFil.DataSet;

namespace ZecaFil.Controls
{
    public partial class SaleXtraForm : XtraForm
    {
        private long _documentId;
        private VendaDataSet _dataSet;
        private Controller _controller;
        private bool _loading;

        #region Properties

        public long DocumentId
        {
            set { _documentId = value; }
        }

        public Controller Controller
        {
            set { _controller = value; }
        }

        #endregion

        public SaleXtraForm()
        {
            InitializeComponent();
            Load += SaleXtraFormLoad;
            okSimpleButton.Click += OkSimpleButtonClick;
            salesmanLookUpEdit.EditValueChanging += SalesmanLookUpEditEditValueChanging;
            gridView.InitNewRow += GridViewInitNewRow;
            DevExpressHelper.SetColumnAsCurrency(colValor);
            DevExpressHelper.SetColumnAsNumeric(colQuantidade);
        }        

        #region Private Methods

        private void SetDocumentData()
        {
            _dataSet = new VendaDataSet();
            if (_documentId == -1)
            {
                var document = _dataSet.Venda.NewVendaRow();
                document.Id = -1;
                document.Vendedor = "";
                document.Morada = "";
                document.Zona = "";
                document.Contacto = "";
                _dataSet.Venda.AddVendaRow(document);
            }
            else
                _dataSet.Merge(_controller.GetSale(_documentId));
        }

        private void SetupSalesmanLookupData()
        {
            vendedorDataSet = _controller.GetSalesmans();
            salesmanLookUpEdit.Properties.Columns.Clear();
            salesmanLookUpEdit.Properties.Columns.AddRange(new[] {
                    new LookUpColumnInfo("Vendedor", "Vendedor", 81, FormatType.None, "", false, HorzAlignment.Near),
                    new LookUpColumnInfo("Nome", "Nome", 85, FormatType.None, "", true, HorzAlignment.Near)});
            salesmanLookUpEdit.Properties.DisplayMember = vendedorDataSet.Vendedor.NomeColumn.ColumnName;
            salesmanLookUpEdit.Properties.ValueMember = vendedorDataSet.Vendedor.VendedorColumn.ColumnName;
            salesmanLookUpEdit.Properties.DataSource = vendedorDataSet.Vendedor;
        }

        private void SetupClientLookupData()
        {
            clienteDataSet = _controller.GetClients();
            clientRepositoryItemLookUpEdit.Columns.Clear();
            clientRepositoryItemLookUpEdit.Columns.AddRange(new[] {
                    new LookUpColumnInfo("Cliente", "Cliente", 81, FormatType.None, "", false, HorzAlignment.Near),
                    new LookUpColumnInfo("Nome", "Nome", 85, FormatType.None, "", true, HorzAlignment.Near)});
            clientRepositoryItemLookUpEdit.DisplayMember = clienteDataSet.Cliente.NomeColumn.ColumnName;
            clientRepositoryItemLookUpEdit.ValueMember = clienteDataSet.Cliente.ClienteColumn.ColumnName;
            clientRepositoryItemLookUpEdit.DataSource = clienteDataSet.Cliente;
        }

        private void SetupServiceDesignationLookupData()
        {
            designacaoServicoDataSet = _controller.GetServiceDesignations();
            serviceDesignationRepositoryItemLookUpEdit.Columns.Clear();
            serviceDesignationRepositoryItemLookUpEdit.Columns.AddRange(new[] {
                    new LookUpColumnInfo("Codigo", "Codigo", 81, FormatType.None, "", false, HorzAlignment.Near),
                    new LookUpColumnInfo("Descricao", "Descricao", 85, FormatType.None, "", true, HorzAlignment.Near)});
            serviceDesignationRepositoryItemLookUpEdit.DisplayMember = designacaoServicoDataSet.DesignacaoServico.DescricaoColumn.ColumnName;
            serviceDesignationRepositoryItemLookUpEdit.ValueMember = designacaoServicoDataSet.DesignacaoServico.CodigoColumn.ColumnName;
            serviceDesignationRepositoryItemLookUpEdit.DataSource = designacaoServicoDataSet.DesignacaoServico;
        }

        private void SetupContractTypeLookupData()
        {
            tipoContractoDataSet = _controller.GetContractTypes();
            contractTypeRepositoryItemLookUpEdit.Columns.Clear();
            contractTypeRepositoryItemLookUpEdit.Columns.AddRange(new[] {
                    new LookUpColumnInfo("Codigo", "Codigo", 81, FormatType.None, "", false, HorzAlignment.Near),
                    new LookUpColumnInfo("Descricao", "Descricao", 85, FormatType.None, "", true, HorzAlignment.Near)});
            contractTypeRepositoryItemLookUpEdit.DisplayMember = tipoContractoDataSet.TipoContracto.DescricaoColumn.ColumnName;
            contractTypeRepositoryItemLookUpEdit.ValueMember = tipoContractoDataSet.TipoContracto.CodigoColumn.ColumnName;
            contractTypeRepositoryItemLookUpEdit.DataSource = tipoContractoDataSet.TipoContracto;
        }

        private void SetupZoneLookupData()
        {
            zonaDataSet = _controller.GetZones();
            zoneLookUpEdit.Properties.Columns.Clear();
            zoneLookUpEdit.Properties.Columns.AddRange(new[] {
                    new LookUpColumnInfo("Nome", "Nome", 85, FormatType.None, "", true, HorzAlignment.Near)});
            zoneLookUpEdit.Properties.DisplayMember = zonaDataSet.Zona.NomeColumn.ColumnName;
            zoneLookUpEdit.Properties.ValueMember = zonaDataSet.Zona.NomeColumn.ColumnName;
            zoneLookUpEdit.Properties.DataSource = zonaDataSet.Zona;
        }

        private void GetDataFromControls()
        {
            if (salesmanLookUpEdit.EditValue == Convert.DBNull || salesmanLookUpEdit.EditValue.ToString() == "")
                _dataSet.Venda[0].SetVendedorNull();
            else
                _dataSet.Venda[0].Vendedor = salesmanLookUpEdit.EditValue.ToString();
            if (zoneLookUpEdit.Text == "")
                _dataSet.Venda[0].SetZonaNull();
            else
                _dataSet.Venda[0].Zona = zoneLookUpEdit.EditValue.ToString();            
            _dataSet.Venda[0].Morada = addressTextEdit.Text;
            _dataSet.Venda[0].Contacto = contactTextEdit.Text;
            gridView.CloseEditor();
            gridView.UpdateCurrentRow();
        }

        private void SetDataToControls()
        {
            salesmanLookUpEdit.EditValue = _dataSet.Venda[0].IsVendedorNull() ? "" : _dataSet.Venda[0].Vendedor;
            zoneLookUpEdit.EditValue = _dataSet.Venda[0].IsZonaNull() ? "" : _dataSet.Venda[0].Zona;
            addressTextEdit.Text = _dataSet.Venda[0].IsMoradaNull() ? "" : _dataSet.Venda[0].Morada;
            contactTextEdit.Text = _dataSet.Venda[0].IsContactoNull() ? "" : _dataSet.Venda[0].Contacto;
            if (!_dataSet.Venda[0].IsVendedorNull())
            {
                VendedorDataSet.VendedorRow salesman = vendedorDataSet.Vendedor.FindByVendedor(Convert.ToString(_dataSet.Venda[0].Vendedor));
                fotoPictureEdit.EditValue = salesman == null || salesman.IsFotoNull() ? Convert.DBNull : salesman.Foto;
            }                
            gridControl.DataSource = null;
            gridControl.DataMember = "";
            gridControl.DataSource = _dataSet;
            gridControl.DataMember = _dataSet.ItemVenda.TableName;
            DevExpressHelper.SetColumnAsCurrency(colValor);
            DevExpressHelper.SetColumnAsNumeric(colQuantidade);
        }

        private void ClearControlErrors()
        {
            dxErrorProvider.SetError(salesmanLookUpEdit, "");
            dxErrorProvider.SetError(zoneLookUpEdit, "");
            dxErrorProvider.SetError(addressTextEdit, "");
            dxErrorProvider.SetError(contactTextEdit, "");
        }

        private Control GetControl(string reference)
        {
            switch (reference)
            {
                case "Vendedor":
                    return salesmanLookUpEdit;
                case "Morada":
                    return addressTextEdit;
                case "Zona":
                    return zoneLookUpEdit;
                case "Contacto":
                    return contactTextEdit;
                default:
                    return null;
            }
        }

        private void SetControlErrors(Result result)
        {
            foreach (var error in result.Errors)
            {
                dxErrorProvider.SetError(GetControl(error.Reference), error.Message);
                if (error.Reference == "ItemVenda")
                    MessageBox.Show(this, error.Message, "Venda", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        #endregion Private Methods

        void SaleXtraFormLoad(object sender, EventArgs e)
        {
            _loading = true;            
            SetDocumentData();
            SetupSalesmanLookupData();
            SetupClientLookupData();
            SetupServiceDesignationLookupData();
            SetupContractTypeLookupData();
            SetupZoneLookupData();
            SetDataToControls();
            _loading = false;
        }

        void SalesmanLookUpEditEditValueChanging(object sender, ChangingEventArgs e)
        {
            if(_loading)
                return;
            if (e.NewValue == null)
            {
                addressTextEdit.Text = "";
                contactTextEdit.Text = "";
                fotoPictureEdit.EditValue = null;
            }
            else
            {
                VendedorDataSet.VendedorRow salesman = vendedorDataSet.Vendedor.FindByVendedor(Convert.ToString(e.NewValue));
                addressTextEdit.Text = salesman.IsMoradaNull() ? "" : salesman.Morada;
                contactTextEdit.Text = salesman.IsTelemovelNull() ? "" : salesman.Telemovel;
                fotoPictureEdit.EditValue = salesman.IsFotoNull() ? Convert.DBNull : salesman.Foto;
            }
        }

        void GridViewInitNewRow(object sender, DevExpress.XtraGrid.Views.Grid.InitNewRowEventArgs e)
        {
            gridView.SetRowCellValue(e.RowHandle, colId, _dataSet.Venda[0].Id);
            gridView.SetRowCellValue(e.RowHandle, colQuantidade, 0);
            gridView.SetRowCellValue(e.RowHandle, colValor, 0);
            gridView.SetRowCellValue(e.RowHandle, colAnulado, false);
        }

        void OkSimpleButtonClick(object sender, EventArgs e)
        {
            ClearControlErrors();
            GetDataFromControls();
            Result result = _controller.IsSaleValid(_dataSet);
            if (result.Failed)
            {
                DialogResult = DialogResult.None;
                SetControlErrors(result);
            }
            else
                _controller.SaveSale(_dataSet);
        }
    }
}